package main

import (
	"context"
	"fmt"
	"interview/initialize"
	"interview/pkg/global"
	"net/http"
	"os"
	"os/signal"
	"runtime/debug"
	"syscall"
	"time"
)

func main() {
	defer func() {
		if err := recover(); err != nil {
			global.Logger.Error(fmt.Sprintf("项目启动失败:  %v\n堆栈信息: %v", err, string(debug.Stack())))
		}
	}()

	// 初始化配置文件
	initialize.InitConfig()

	// 初始化全局日志
	initialize.Logger()

	// 初始化Redis
	if global.Conf.System.EnableRedis {
		initialize.Redis()
	}

	// 初始化数据库
	initialize.Mysql()

	// 初始化校验器
	initialize.Validator()

	global.Logger.Info(global.Conf)

	// 初始化路由
	r := initialize.Routers()
	host := "0.0.0.0"

	srv := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", host, global.Conf.System.Port),
		Handler: r,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			global.Logger.Errorf("listen: %s", err.Error())
		}
	}()
	// 初始化数据
	//initialize.InitData()
	global.Logger.Infof("Server is running at port %d...", global.Conf.System.Port)

	// 接收关闭信号
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	global.Logger.Info("Server is shutting down...")
	ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
	defer cancelFunc()
	if err := srv.Shutdown(ctx); err != nil {
		global.Logger.Error("Server forced to shutdown: ", err)
	}

	global.Logger.Info("Server exited")
}
